# 均方误差
import numpy as np


def mean_squared_error(y, t):
    return 0.5 * np.sum((y - t) ** 2)

# 设"2"为正确解
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

print("均方误差")
# 例 1：“2”的概率最高的情况（0.6）
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print(mean_squared_error(np.array(y), np.array(t)))

# 例 2：“7”的概率最高的情况（ 0.6）
y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print(mean_squared_error(np.array(y), np.array(t)))


# 交叉熵误差
# 交叉熵误差的值是由正确解标签所对应的输出结果决定的。
def cross_entropy_error(y, t):
    # 1e-7 是科学计数法，表示很小的数。
    # e 在 Python 里不是科学计数法的“e”，而是数学常数。
    # 所以要写 1e-7，不能只写 e。
    delta = 1e-7
    return -np.sum(t * np.log(y + delta))

print("交叉熵误差")
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print(cross_entropy_error(np.array(y), np.array(t)))

y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print(cross_entropy_error(np.array(y), np.array(t)))


# 普通的乘法，不是矩阵乘法 one-hot表示
def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
    batch_size = y.shape[0]
    return -np.sum(t * np.log(y + 1e-7)) / batch_size

# 非one-hot表示
# y是神经网络的输出，t是监督数据
def cross_entropy_error_complete(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
    batch_size = y.shape[0]
    if t.size == y.size:  # 如果t是one-hot编码
        return -np.sum(t * np.log(y + 1e-7)) / batch_size
    else:  # 如果t是数字标签
        return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size